home *** CD-ROM | disk | FTP | other *** search
- From: argv@zipcode.com (Dan Heller)
- Newsgroups: comp.sources.misc
- Subject: v18i077: mush - Mail User's Shell, Part20/22
- Message-ID: <1991Apr22.153808.111@sparky.IMD.Sterling.COM>
- Date: 22 Apr 91 15:38:08 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: b5859633 d851a387 5114387f a5d58b5a
-
- Submitted-by: Dan Heller <argv@zipcode.com>
- Posting-number: Volume 18, Issue 77
- Archive-name: mush/part20
- Supersedes: mush: Volume 12, Issue 28-47
-
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file pick.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 20; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping pick.c'
- else
- echo 'x - continuing file pick.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'pick.c' &&
- X * 1d 1Y
- X *
- X * Return number of args parsed; -1 on error.
- X */
- ago_date(argv)
- char **argv;
- {
- #define SECS_PER_DAY (60 * 60 * 24)
- #define SECS_PER_WEEK (SECS_PER_DAY * 7)
- #define SECS_PER_MONTH ((int)(SECS_PER_DAY * 30.5))
- #define SECS_PER_YEAR (SECS_PER_DAY * 365)
- X register char *p;
- X char buf[256];
- X int n = 0, value;
- X long t;
- X struct tm *today;
- X
- X (void) argv_to_string(buf, argv);
- X p = buf;
- X (void) time (&t); /* get current time in seconds and subtract new values */
- X if (*p == '-')
- X before = TRUE;
- X else if (*p == '+')
- X after = TRUE;
- X skipspaces(before || after);
- X while (*p) {
- X if (!isdigit(*p)) {
- X p -= 2;
- X break; /* really a syntax error, but it could be other pick args */
- X }
- X p = my_atoi(p, &value); /* get 1 or more digits */
- X skipspaces(0); /* 0 or more spaces */
- X switch (lower(*p)) { /* d, m, or y */
- X case 'd' : t -= value * SECS_PER_DAY;
- X when 'w' : t -= value * SECS_PER_WEEK;
- X when 'm' : t -= value * SECS_PER_MONTH;
- X when 'y' : t -= value * SECS_PER_YEAR;
- X otherwise: return -1;
- X }
- X for (p++; Lower(*p) >= 'a' && *p <= 'z'; p++)
- X ; /* skip the rest of this token */
- X while (*p == ',' || isspace(*p))
- X ++p; /* 0 or more whitespaces or commas */
- X }
- X today = localtime(&t);
- X mdy[0] = today->tm_mon;
- X mdy[1] = today->tm_mday;
- X mdy[2] = today->tm_year;
- X
- X /* Count the number of args parsed */
- X for (n = 0; p > buf && *argv; n++)
- X p -= (strlen(*argv++)+1);
- X Debug("parsed %d args\n", n);
- X return n;
- }
- SHAR_EOF
- echo 'File pick.c is complete' &&
- chmod 0644 pick.c ||
- echo 'restore of pick.c failed'
- Wc_c="`wc -c < 'pick.c'`"
- test 17697 -eq "$Wc_c" ||
- echo 'pick.c: original size 17697, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= print.c ==============
- if test -f 'print.c' -a X"$1" != X"-c"; then
- echo 'x - skipping print.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting print.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'print.c' &&
- /* @(#)print.c 2.4 (c) copyright 10/15/86 (Dan Heller) */
- X
- #include "mush.h"
- #include <varargs.h>
- X
- /*ARGSUSED*/
- /*VARARGS1*/
- void
- error(fmt, arg1, arg2, arg3, arg4)
- register char *fmt;
- char *arg1, *arg2, *arg3, *arg4;
- {
- X char buf[BUFSIZ];
- X
- X (void) sprintf(buf, fmt, arg1, arg2, arg3, arg4);
- X sprintf(buf+strlen(buf), ": %s\n", sys_errlist[errno]);
- #ifdef SUNTOOL
- X if (istool > 1)
- X ok_box(buf);
- X else
- #endif /* SUNTOOL */
- X print(buf);
- }
- X
- #if defined(SUNTOOL) || defined(CURSES)
- /*
- X * print just like printf -- to a window, to curses, or to stdout. Use vprintf
- X * if available. msgbuf is the buffer used to print into if necessary.
- X * If you're running SUN3.2 or higher, the typecast (unsigned char *)msgbuf
- X * (where indicated) otherwise, msgbuf is not typecast at all.
- X */
- /*VARARGS*/
- void
- print(va_alist)
- va_dcl
- {
- X static char msgbuf[BUFSIZ];
- X char *fmt;
- X va_list args;
- #ifndef VPRINTF
- X FILE foo;
- #endif /* VPRINTF */
- X static int x; /* position on line saved for continued prints */
- X char *p; /* same type as struct file _ptr,_buf in stdio.h */
- X
- #ifdef CURSES
- X if (iscurses) {
- X if (isoff(glob_flags, CONT_PRNT))
- X move(LINES-1, x = 0), refresh();
- X } else
- #endif /* CURSES */
- X if (istool < 2) {
- X va_start(args);
- X fmt = va_arg(args, char *);
- #ifdef VPRINTF
- X (void) vprintf(fmt, args);
- #else /* VPRINTF */
- X _doprnt(fmt, args, stdout);
- #endif /* VPRINTF */
- X va_end(args);
- X (void) fflush(stdout);
- X return;
- X }
- X va_start(args);
- X fmt = va_arg(args, char *);
- X if (fmt) {
- #ifdef VPRINTF
- X (void) vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
- #else /* VPRINTF */
- X foo._cnt = BUFSIZ;
- X foo._base = foo._ptr = msgbuf; /* may have to cast(unsigned char *) */
- X foo._flag = _IOWRT+_IOSTRG;
- X (void) _doprnt(fmt, args, &foo);
- X *foo._ptr = '\0'; /* plant terminating null character */
- #endif /* VPRINTF */
- X }
- X va_end(args);
- X if (istool) {
- X wprint("%s", msgbuf);
- X return;
- X }
- X p = msgbuf;
- X if (iscurses)
- X while (p = index(p, '\n'))
- X *p = ' ';
- #ifdef CURSES
- X if (iscurses) {
- X p = msgbuf;
- X for (;;) {
- X int len = COLS-1-x; /* space remaining at till the eol */
- X /* don't wrap the line! Just print it and refresh() */
- X printw("%-.*s", len, p), clrtoeol(), refresh();
- X /* if length(p) (remainder of msgbuf) doesn't wrap, break loop */
- X if ((x += strlen(p)) < COLS-1)
- X break;
- X /* the next print will overwrite bottom line, so \n first */
- X putchar('\n'), move(LINES-1, x = 0); /* reset x */
- X /* move p forward the number of chars we were able to display */
- X p += len;
- X turnon(glob_flags, CNTD_CMD); /* display ...continue... prompt */
- X }
- X turnoff(glob_flags, CONT_PRNT);
- X (void) fflush(stdout); /* some sys-v's aren't fflushing \n's */
- X return;
- X }
- #endif /* CURSES */
- }
- X
- #endif /* SUNTOOL || CURSES */
- X
- /* for curses mode */
- clr_bot_line()
- {
- X print("");
- }
- X
- #ifdef SUNTOOL
- X
- /*
- X * wprint prints stuff to a scrollable textsw. This is intended for
- X * print statements that need to be recalled since print() overwrites
- X * its last message.
- X * For non-suntool mode, wprint() is just like printf(). For curses mode,
- X * wprint() does -not- act like print() -- lines length is not counted
- X * and newlines are not stripped.
- X */
- /*VARARGS*/
- void
- wprint(va_alist)
- va_dcl
- {
- #ifndef VPRINTF
- X FILE foo;
- #endif /* VPRINTF */
- X char msgbuf[BUFSIZ]; /* we're not getting huge strings */
- X char *fmt;
- X va_list args;
- X
- X if (istool < 2) {
- X va_start(args);
- X fmt = va_arg(args, char *);
- #ifdef VPRINTF
- X (void) vprintf(fmt, args);
- #else /* VPRINTF */
- X _doprnt(fmt, args, stdout);
- #endif /* VPRINTF */
- X va_end(args);
- X (void) fflush(stdout);
- X return;
- X }
- X
- X if (!mfprint_sw)
- X return;
- X va_start(args);
- X fmt = va_arg(args, char *);
- X if (fmt) {
- #ifdef VPRINTF
- X (void) vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
- #else /* VPRINTF */
- X foo._cnt = BUFSIZ;
- X foo._base = foo._ptr = msgbuf; /* may have to cast (unsigned char *) */
- X foo._flag = _IOWRT+_IOSTRG;
- X _doprnt(fmt, args, &foo); /* format like printf into msgbuf via foo */
- X *foo._ptr = '\0'; /* plant terminating null character */
- #endif /* VPRINTF */
- X textsw_insert(mfprint_sw, msgbuf, strlen(msgbuf));
- X }
- X va_end(args);
- }
- X
- #include <sundev/kbio.h>
- #include <sundev/kbd.h>
- X
- bell()
- {
- #ifdef KIOCCMD
- X if (istool) {
- X int kbd = open("/dev/kbd", O_WRONLY, 0);
- X struct timeval timer;
- X timer.tv_sec = 0;
- X timer.tv_usec = 100000;
- X if (kbd != -1) {
- X int cmd = KBD_CMD_BELL;
- X (void) ioctl(kbd, KIOCCMD, &cmd);
- X (void) select(32, (fd_set *) 0,(fd_set *) 0,(fd_set *) 0, &timer);
- X cmd = KBD_CMD_NOBELL;
- X (void) ioctl(kbd, KIOCCMD, &cmd);
- X (void) close(kbd);
- X }
- X } else
- #endif /* KIOCCMD */
- X (void) fputc('\007', stderr), (void) fflush(stderr);
- X return 0;
- }
- X
- #endif /* SUNTOOL */
- X
- #ifdef BSD
- #undef fputs
- X
- /*
- X * The standard 4.x BSD fputs() does not return any useful value.
- X * For compatibility with Sun and SysV fputs(), we use this wrapper.
- X */
- X
- Fputs(line, fp)
- char *line;
- FILE *fp;
- {
- X clearerr(fp);
- X (void) fputs(line, fp);
- X if (ferror(fp))
- X return EOF;
- X return 0;
- }
- X
- #endif /* BSD */
- SHAR_EOF
- chmod 0644 print.c ||
- echo 'restore of print.c failed'
- Wc_c="`wc -c < 'print.c'`"
- test 5154 -eq "$Wc_c" ||
- echo 'print.c: original size 5154, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= sample.mushrc ==============
- if test -f 'sample.mushrc' -a X"$1" != X"-c"; then
- echo 'x - skipping sample.mushrc (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting sample.mushrc (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'sample.mushrc' &&
- # sample.mushrc
- # By Bart Schaefer and Dan Heller
- #
- # Change mush's temp file directory, to avoid quota collisions.
- # /usr/tmp so tmpfiles won't be rm'd before they can be recovered.
- set tmpdir=/usr/tmp
- X
- # Set the folder and mbox locations; the + expands to value of "folder".
- set folder=$HOME/Mail mbox=+mbox
- X
- # Set up the display early to allow quick exit in headers-only mode.
- # The hdrs_only flag is true if the command line was: "mush -H".
- # The variable hdr_format is set to change the format of the header
- # summaries that are displayed.
- if hdrs_only
- X set hdr_format='%28a %M %-2N %.33s'
- X exit # Quits reading this file
- else
- X set hdr_format='%28a %M %-2N (%3.5l li) %.25s'
- endif
- X
- # Set the prompt to show current time, name of the current folder,
- # current message number, and count of total messages.
- set prompt="(%T) %f: #%m of %t> "
- X
- # Hitting <CR> should do nothing (helps make mush more shell-like). If
- # newline is not set, hitting <CR> prints the next message (like Mail).
- # This variable could be set to any mush command.
- set newline
- X
- # These variables are helpful for new users:
- # ask -- always prompt for Subject: of mail
- # ignoreeof -- ignore end-of-file from keyboard
- # verify -- query that all is well before sending mail
- # warning -- report miscellaneous possible problems
- set ask verify warning
- set ignoreeof="echo 'Use "'"'quit'"'" to quit.'"
- X
- # When reading messages, don't bother looking at lengthy, boring headers.
- ignore message-id received via status
- X
- # Since mush has csh-like history, you might find it annoying to type
- # things like "mail host\!host1\!host2\!user" from within the mush shell.
- # Setting nonobang will prevent the "unknown event" and allow the !'s to
- # be typed without having to be preceded by backslashes.
- set nonobang
- X
- # By default, mush's history is set to the last command only. Set it to
- # remember the last 100 commands.
- set history = 100
- X
- # If the variable "unix" is set, then any command that isn't a mush command
- # will execute the command as if you typed it from the shell. Note, such
- # commands will not go through another shell -- this is it.
- set unix
- X
- # Mush tries to read ~/.mushrc first, then it tries ~/.mailrc. Assuming
- # you use *this* file as your .mushrc, source the contents of .mailrc as
- # well in case there are Mail aliases that are set there.
- source $HOME/.mailrc
- X
- # Use a real pager.
- set pager=less
- X
- # When typing in a letter, it is sometimes convenient to have lines wrap
- # automatically similar to editors like vi and emacs. In this example, if
- # the user types past column 74, a newline will automatically be inserted.
- set wrapcolumn=74
- X
- # If "autosign" is set, then a file can be read in automatically whenever
- # mail is sent. This file is normally your "signature," that is, your
- # name and other information you want included in every message.
- set autosign = ~/.signature
- X
- # When you use the -i option to reply, or use the ~i tilde escape in a letter
- # when in compose mode, the current message will be included in your text.
- # Put a nice wrapper around those included messages. Here, show the author's
- # name and the subject of his letter, label the end, and add a trailing blank
- # to separate each inclusion and make finding the end easier.
- set pre_indent_str='On %M %N, %T, %.50n wrote:\n} Subject: %.65s'
- set indent_str='} ' # actual message text is preceded by a "}"
- set post_indent_str='}-- End of excerpt from %.50n\n'
- X
- # Label replies with a header showing the who, what, and when of the
- # message being replied-to.
- set in_reply_to='%f\n\t"%s" (%d)'
- X
- # Mail routing and address-fixing conveniences. If auto_route is set, then
- # replies to messages take a closer look at the addresses of the recipients.
- # If any redundant paths are present, they are pruned. Also, the path that
- # precedes any hosts listed in the "known_hosts" list is truncated. This is
- # useful for uucp sites only, and is therefore commented out in this sample.
- # set auto_route known_hosts="sun ucbcad well unicom"
- X
- # The "alts" command specifies alternate addresses that I have. Here,
- # "*" expands to any "path" whose recipient ends with the user's current
- # login name. If another login name is desired, the login and/or path
- # to that login must be preceded by a !. Otherwise, standard paths are used.
- alts "*"
- X
- # The "map" command can rebind certain key sequences in tty-mode only.
- # Here, if the user types two R's in a row at the prompt, then the string
- # "reply -ei " will be echoed as if the user typed it.
- map RR "reply -ei "
- # "rr" will do a reply and do the newline for you so you don't have to.
- map rr "reply\n"
- X
- # The "map!" command is similar to "map" in that you can do keyboard
- # acceleration, but map! occurs during letter composition mode only.
- map! '\CT' ' ' # ^T generates 4 spaces in composition mode.
- # Here, hitting * twice will append a pre-signature.
- map! ** "\n Later,\n"
- X
- # Be careful with map and map! -- you can cause an infinite loop.
- # Your interrupt key (usually ^C) will stop such loops.
- X
- # The curses mode allows the screen to be set up like a full screen editor.
- # There are basic "curses commands" which are bound to keyboard key-sequences
- # (usually one character). The user can rebind these keys to suit his tastes.
- # Note that the binding for R below removes the binding of reply-all.
- #
- set curses_help # Unset this to remove help message in curses.
- bind \n display # Hit return to display the next message.
- bind t top # Make it easier to see the top few lines.
- bind e macro "[line-mode]edit\n" # Quick edit from curses.
- bind P macro "[line-mode]Print\n" # Show me all the headers.
- bind R macro "[line-mode]reply -ei " # Reply with inclusion and edit.
- bind A macro "R[getline]~t\n\CUargv\n" # R to Dan w/auto address fix.
- X
- # "cmd" is used to set command line aliases similar to the way "csh"
- # does it. The only difference is that "alias" is a reserved word in
- # Mush and Mail, so cmd is used.
- #
- cmd dq 'd \!*; q' # Delete a message list, then quit.
- cmd unread 'flags \!* U O' # Mark messages unread.
- cmd : curses # Colon now "toggles" curses mode.
- X
- # Find messages from mailer-daemon (ignore upper/lower case).
- cmd md 'pick -i -f mailer-daemon'
- # Because mush can pipe commands to one another, including "cmd"'s, this
- # example will delete all messages from mailer-daemon
- cmd dmd 'md | delete'
- X
- # aliases -- just like Mail's, but you can specify "names"
- alias argv Dan Heller <argv@sun.com>
- alias bart Bart Schaefer <schaefer@cse.ogi.edu>
- alias mush-users Mush Users <mush-users-request@apple.com>
- SHAR_EOF
- chmod 0644 sample.mushrc ||
- echo 'restore of sample.mushrc failed'
- Wc_c="`wc -c < 'sample.mushrc'`"
- test 6535 -eq "$Wc_c" ||
- echo 'sample.mushrc: original size 6535, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= setopts.c ==============
- if test -f 'setopts.c' -a X"$1" != X"-c"; then
- echo 'x - skipping setopts.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting setopts.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'setopts.c' &&
- /* setopts.c (c) copyright 1986 (Dan Heller) */
- X
- #include "mush.h"
- #include "bindings.h"
- X
- static void
- insert_option(list, opt, order)
- struct options **list, *opt;
- int order; /* Insert in sorted order? */
- {
- X while (*list && (!order || (strcmp((*list)->option, opt->option) < 1)))
- X list = &((*list)->next);
- X opt->next = *list;
- X *list = opt;
- }
- X
- /* add an option indicated by "set option[=value]" or by "alias name alias"
- X * function is recursive, so multilists get appended accordingly
- X */
- add_option(list, argv)
- register struct options **list;
- register char **argv;
- {
- X register struct options *tmp;
- X register char *option, *value = NULL;
- X
- X if (!(option = *argv))
- X return 1;
- X /* check for one of three forms:
- X * option=value option= value option = value
- X */
- X if (value = index(option, '=')) {
- X if (value == option) {
- X print("No variable specified\n");
- X return 0;
- X }
- X /* "option=value" strip into option="option" value="value" */
- X *value++ = 0; /* option is now a null terminated `option' */
- X if (*value || (value = *++argv)) { /* "option= value" */
- X ++argv;
- X }
- X } else if (*++argv && !strcmp(*argv, "=")) {
- X if (value = *++argv) /* "option = value" */
- X ++argv;
- X }
- X
- X /* check for internal vars that can't be set this way */
- X if (*list == set_options && check_internal(option)) {
- X print("You can't change %s with \"set\".\n", option);
- X return 0;
- X }
- X
- X /* check to see if option is already set by attempting to unset it */
- X if (un_set(list, option) == -1)
- X return 0;
- X
- X /* now make a new option struct and set fields */
- X if (!(tmp = (struct options *)calloc((unsigned)1,sizeof(struct options)))) {
- X error("calloc");
- X return -1;
- X }
- X tmp->option = savestr(option);
- X tmp->value = savestr(value); /* strdup handles the NULL case */
- X
- X insert_option(list, tmp, (list != &own_hdrs));
- X
- X /* check for options which must have values or are used frequently */
- X if (*list == set_options) {
- #if defined(CURSES) || defined(SUNTOOL)
- X if (!strcmp(tmp->option, "no_reverse"))
- X turnoff(glob_flags, REV_VIDEO);
- X else
- #endif /* CURSES || SUNTOOL */
- #ifdef SUNTOOL
- X if (!strcmp(tmp->option, "tool_help"))
- X if (tmp->value && *(tmp->value))
- X strdup(tool_help, tmp->value);
- X else {
- X int n = 0;
- X char *p = getpath(TOOL_HELP, &n);
- X if (n)
- X strdup(tool_help, "tool_help");
- X else
- X strdup(tool_help, p);
- X strdup(tmp->value, tool_help);
- X }
- X else
- #endif /* SUNTOOL */
- X if (!strcmp(tmp->option, "cmd_help"))
- X if (tmp->value && *(tmp->value))
- X strdup(cmd_help, tmp->value);
- X else {
- X int n = 0; /* don't ignore no such file or directory */
- X char *p = getpath(COMMAND_HELP, &n);
- X if (n)
- X strdup(cmd_help, "cmd_help");
- X else
- X strdup(cmd_help, p);
- X strdup(tmp->value, cmd_help);
- X }
- X else if (!strcmp(tmp->option, "prompt"))
- X prompt = (tmp->value)? tmp->value : DEF_PROMPT;
- X else if (!strcmp(tmp->option, "warning"))
- X turnon(glob_flags, WARNING);
- X else if (!strcmp(tmp->option, "mil_time"))
- X turnon(glob_flags, MIL_TIME);
- #ifndef MSG_SEPARATOR
- X else if (!strcmp(tmp->option, "date_received"))
- X turnon(glob_flags, DATE_RECV);
- #endif /* MSG_SEPARATOR */
- X else if (!strcmp(tmp->option, "escape")) {
- X escape = (tmp->value)? tmp->value : DEF_ESCAPE;
- X escape[1] = 0; /* only one character, please */
- X } else if (!strcmp(tmp->option, "hdr_format"))
- X hdr_format = (tmp->value)? tmp->value : DEF_HDR_FMT;
- X else if (!strcmp(tmp->option, "crt")) {
- X if (!istool)
- X crt = (tmp->value)? max(atoi(tmp->value), 2): 18;
- X }
- X else if (!strcmp(tmp->option, "screen")) {
- X screen = (tmp->value)? max(atoi(tmp->value), 1): 18;
- #ifdef CURSES
- X if (iscurses && screen > LINES-2)
- X screen = LINES-2;
- #endif /* CURSES */
- X } else if (!strcmp(tmp->option, "wrapcolumn")) {
- X char wval[16];
- X wrapcolumn =
- X (tmp->value && *(tmp->value))? max(atoi(tmp->value), 0): 78;
- #ifdef CURSES
- X /* Use COLS-2 because of silly terminals like vt100 */
- X if (iscurses && wrapcolumn > COLS - 2)
- X wrapcolumn = COLS - 2;
- #endif /* CURSES */
- X xfree(tmp->value);
- X tmp->value = savestr(sprintf(wval, "%d", wrapcolumn));
- X } else if (!strcmp(tmp->option, "history"))
- X init_history((value && *value)? atoi(value) : 1);
- X else if (!strcmp(tmp->option, "realname")) {
- X char *new[4];
- X new[1] = "NAME";
- X new[2] = tmp->value;
- X new[3] = NULL;
- X (void) Setenv(3, new); /* new[0] is ignored */
- X } else if (!strcmp(tmp->option, "known_hosts")) {
- X register char *p;
- X int n;
- X /* in case user separated with commas */
- X for (p = index(tmp->value, ','); p; p = index(p+1, ','))
- X *p = ' ';
- X free_vec(known_hosts);
- X known_hosts = mk_argv(tmp->value, &n, FALSE);
- X } else if (!strcmp(tmp->option, "hostname")) {
- X register char *p;
- X int n;
- X /* in case user separated with commas */
- X for (p = index(tmp->value, ','); p; p = index(p+1, ','))
- X *p = ' ';
- X free_vec(ourname);
- X ourname = mk_argv(tmp->value, &n, FALSE);
- X } else if (!strcmp(tmp->option, "complete")) {
- X if (value && *value) {
- X m_xlate(value); /* use the original, don't change tmp->value */
- X complete = value[0];
- X complist = value[1];
- X } else {
- X tmp->value = savestr("\\E\\CD");
- X complete = '\033';
- X complist = '\004';
- X }
- X }
- X }
- X
- X if (*argv)
- X return add_option(list, argv);
- X return 1;
- }
- X
- /*
- X * If str is NULL, just print options and their values. Note that numerical
- X * values are not converted to int upon return. If str is not NULL
- X * return the string that matched, else return NULL;
- X */
- char *
- do_set(list, str)
- register struct options *list;
- register char *str;
- {
- X register struct options *opts;
- X
- X if (!str)
- X (void) do_pager(NULL, TRUE); /* page using internal pager */
- X
- X for (opts = list; opts; opts = opts->next)
- X if (!str) {
- X (void) do_pager(opts->option, FALSE);
- X if (opts->value && *opts->value) {
- X (void) do_pager(" \t", FALSE);
- X (void) do_pager(opts->value, FALSE);
- X }
- X if (do_pager("\n", FALSE) == EOF)
- X break;
- X } else {
- X if (strcmp(str, opts->option))
- X continue;
- X if (opts->value)
- X return opts->value;
- X else
- X return "";
- X }
- X
- X if (!str)
- X (void) do_pager(NULL, FALSE); /* terminate internal pager */
- X
- X /* if we still haven't matched, check for environment vars */
- X if (str && list == set_options) {
- X register int N, n;
- X for (N = 0; environ[N]; N++) {
- X char *p = index(environ[N], '=');
- X if (p)
- X *p = 0;
- X n = lcase_strncmp(str, environ[N], -1);
- X if (p)
- X *p = '=';
- X if (!n)
- X return p+1;
- X }
- X }
- X return NULL;
- }
- X
- /*
- X * unset the variable described by p in the list "list".
- X * if the variable isn't set, then return 0, else return 1.
- X */
- un_set(list, p)
- register struct options **list;
- register char *p;
- {
- X register struct options *opts = *list, *tmp;
- X
- X if (!list || !*list || !p || !*p)
- X return 0;
- X if (*list == set_options) {
- #if defined(CURSES) || defined(SUNTOOL)
- X if (!strcmp(p, "no_reverse"))
- X turnon(glob_flags, REV_VIDEO);
- X else
- #endif /* CURSES || SUNTOOL */
- X if (!strcmp(p, "prompt"))
- X prompt = DEF_PROMPT;
- X else if (!strcmp(p, "warning"))
- X turnoff(glob_flags, WARNING);
- X else if (!strcmp(p, "mil_time"))
- X turnoff(glob_flags, MIL_TIME);
- #ifndef MSG_SEPARATOR
- X else if (!strcmp(p, "date_received"))
- X turnoff(glob_flags, DATE_RECV);
- #endif /* MSG_SEPARATOR */
- X else if (!strcmp(p, "escape"))
- X escape = DEF_ESCAPE;
- X else if (!strcmp(p, "hdr_format"))
- X hdr_format = DEF_HDR_FMT;
- X else if (!strcmp(p, "crt"))
- X crt = 18;
- X else if (!strcmp(p, "screen")) {
- X screen = 18;
- #ifdef CURSES
- X if (iscurses && screen > LINES-2)
- X screen = LINES-2;
- #endif /* CURSES */
- X } else
- #ifdef SUNTOOL
- X if (!strcmp(p, "tool_help")) {
- X int n = 0;
- X char *p2 = getpath(TOOL_HELP, &n);
- X if (n)
- X strdup(tool_help, "tool_help");
- X else
- X strdup(tool_help, p2);
- X } else
- #endif /* SUNTOOL */
- X if (!strcmp(p, "cmd_help")) {
- X int n = 0; /* don't ignore no such file or directory */
- X char *p2 = getpath(COMMAND_HELP, &n);
- X if (n)
- X strdup(cmd_help, "cmd_help");
- X else
- X strdup(cmd_help, p2);
- X } else if (!strcmp(p, "wrapcolumn"))
- X wrapcolumn = 0;
- X else if (!strcmp(p, "history"))
- X init_history(1);
- X else if (!strcmp(p, "known_hosts")) {
- X free_vec(known_hosts);
- X known_hosts = DUBL_NULL;
- X } else if (!strcmp(p, "hostname")) {
- X free_vec(ourname);
- X ourname = DUBL_NULL;
- X } else if (ison(glob_flags, IS_GETTING) && !strcmp(p, "edit_hdrs")) {
- X wprint("You must finish this letter first.\n");
- X return -1;
- X } else if (!strcmp(p, "complete"))
- X complete = complist = 0;
- #ifdef SUNTOOL
- X else if (!strcmp(p, "compose_icon")) {
- X if (ison(glob_flags, IS_GETTING)) {
- X wprint("You must finish this letter first.\n");
- X return -1;
- X } else
- X /* destroy compose frame so that it is recreated
- X * later as the proper type (base frame or subframe).
- X */
- X if (compose_frame)
- X destroy_compose();
- X }
- #endif
- X }
- X
- X if (!strcmp(p, opts->option)) {
- X *list = (*list)->next;
- X xfree (opts->option);
- X if (opts->value)
- X xfree(opts->value);
- X xfree((char *)opts);
- X return 1;
- X }
- X for ( ; opts->next; opts = opts->next)
- X if (!strcmp(p, opts->next->option)) {
- X tmp = opts->next;
- X opts->next = opts->next->next;
- X xfree (tmp->option);
- X if (tmp->value)
- X xfree(tmp->value);
- X xfree ((char *)tmp);
- X return 1;
- X }
- X return 0;
- }
- X
- /* The functions below return 0 since they don't affect
- X * messages.
- X */
- set(n, argv, list)
- register int n;
- register char **argv;
- char *list;
- {
- X void list_to_str();
- X char firstchar = **argv;
- X register char *cmd = *argv;
- X register struct options **optlist;
- X char buf[BUFSIZ];
- X
- X if (*cmd == 'u')
- X cmd += 2;
- X if (*++argv && !strcmp(*argv, "-?"))
- X return help(0, (*cmd == 'i')? "ignore": "set", cmd_help);
- X
- X if (*argv && **argv == '?') {
- X int incurses;
- X if (!strcmp(*argv, "?all")) {
- X if (incurses = iscurses) /* assign and compare to TRUE */
- X clr_bot_line(), iscurses = FALSE;
- X (void) do_pager(NULL, TRUE); /* start internal pager */
- X for (n = 0; variable_stuff(n, NULL, buf); n++)
- X if (do_pager(strcat(buf, "\n"), FALSE) == EOF)
- X break;
- X (void) do_pager(NULL, FALSE); /* terminate pager */
- X iscurses = incurses;
- X } else {
- X /* May return null if variable not set. */
- X (void) variable_stuff(0, (*argv)+1, buf);
- X print("%s\n", buf);
- X }
- X return 0;
- X }
- X
- X if (firstchar == 'u') {
- X if (!*argv) {
- X print("%s what?\n", cmd);
- X return -1;
- X } else {
- X optlist = (*cmd == 'i')? &ignore_hdr : &set_options;
- X do if (!strcmp(*argv, "*")) {
- X while (*optlist)
- X (void) un_set(optlist, (*optlist)->option);
- #ifdef SUNTOOL
- X if (*cmd != 'i')
- X opts_panel_item(NULL);
- #endif /* SUNTOOL */
- X } else if (!un_set(optlist, *argv) &&
- X do_set(set_options, "warning"))
- X print("un%s: %s not set\n",
- X (*cmd == 'i')? "ignore" : "set", *argv);
- #ifdef SUNTOOL
- X else if (*cmd != 'i')
- X opts_panel_item(*argv);
- #endif /* SUNTOOL */
- X while (*++argv);
- #ifdef SUNTOOL
- X if (*cmd == 'i' && istool > 1)
- X update_list_textsw(&ignore_hdr);
- #endif /* SUNTOOL */
- X }
- X return 0;
- X }
- X
- X if (!*argv) {
- X (void) do_set((*cmd == 'i')? ignore_hdr: set_options, NULL);
- X return 0;
- X }
- X
- X /*
- X * Check for input redirection. If so, set the variable to the ascii
- X * value of the current msg_list.
- X */
- X if (ison(glob_flags, IS_PIPE)) {
- X char *newargv[4];
- X
- X if (*cmd == 'i') {
- X print("You can't pipe to the \"%s\" command.\n", cmd);
- X return -1;
- X }
- X if (newargv[0] = index(argv[0], '='))
- X *newargv[0] = 0;
- X list_to_str(list, buf);
- X if (!buf[0] && !do_set(set_options, argv[0])) {
- X return 0;
- X }
- X newargv[0] = argv[0];
- X newargv[1] = "=";
- X newargv[2] = buf;
- X newargv[3] = NULL;
- X (void) add_option(&set_options, newargv);
- X return 0;
- X }
- X
- X /*
- X * finally, just set the variable the user requested.
- X */
- X (void) add_option((*cmd == 'i')? &ignore_hdr: &set_options, argv);
- #ifdef SUNTOOL
- X if (istool > 1)
- X if (*cmd == 'i')
- X update_list_textsw(&ignore_hdr);
- X else
- X opts_panel_item(argv[0]);
- #endif /* SUNTOOL */
- X return 0;
- }
- X
- /*
- X * The alts list is a list of hostnames or pathnames where the user
- X * has an account. If he doesn't specify "metoo", then when replying
- X * to mail, if his address is listed, it will be removed. The syntax
- X * is compatible with ucb Mail in that just hostnames can be used.
- X * However, there is an added feature that mush provides which another
- X * login name or path to another login can be specified by preceding the
- X * path or login with a !
- X * "argv" may be a file pointer to write the data into by use of save_opts()
- X */
- alts(argc, argv)
- register char **argv;
- {
- X char buf[BUFSIZ], *p;
- X
- X /* check here first because a 0 argc means to write it to a file */
- X if (argc <= 1) {
- X int n;
- X if (!alternates)
- X return 0;
- X if (argc == 0)
- X (void) fprintf((FILE *)argv, "alts ");
- X for (n = 0; alternates[n]; n++) {
- X p = 0;
- X buf[0] = 0;
- X (void) strcpy(&buf[1], alternates[n]);
- X if (buf[1] != '*')
- X (void) reverse(&buf[1]);
- X if ((p = rindex(&buf[1], '!')) && !lcase_strncmp(p+1, login, -1))
- X *p = 0;
- X else if (buf[1] != '*')
- X buf[0] = '!';
- X if (argc == 0)
- X (void) fprintf((FILE *)argv, "%s ", *buf? buf : &buf[1]);
- X else
- X wprint("%s ", *buf? buf : &buf[1]);
- X if (p)
- X *p = '!';
- X }
- X if (argc == 0)
- X (void) fputc('\n', (FILE *)argv);
- X else
- X wprint("\n");
- X return 0;
- X }
- X
- X if (argc-- && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "alts", cmd_help);
- X
- X free_vec(alternates);
- X if (alternates = (char **)calloc((unsigned)argc+1, sizeof(char *)))
- X while (argc-- > 0) {
- X if (argv[argc][0] == '!')
- X alternates[argc] = savestr(reverse(&argv[argc][1]));
- X else if (argv[argc][0] == '*') {
- X alternates[argc] = savestr(argv[argc]);
- X } else {
- X if (index(argv[argc], '@'))
- X bang_form(buf, argv[argc]);
- X else {
- X p = buf + Strcpy(buf, argv[argc]);
- X *p++ = '!', p += Strcpy(p, login);
- X }
- X alternates[argc] = savestr(reverse(buf));
- X }
- X }
- X return 0;
- }
- X
- save_opts(cnt, argv)
- char **argv;
- {
- X char file[MAXPATHLEN], *tmp;
- X register FILE *fp;
- X
- X if (cnt && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "source", cmd_help);
- X if (cnt && *argv)
- X (void) strcpy(file, *argv);
- X else if ((tmp = getenv("MUSHRC")) || (tmp = getenv("MAILRC")))
- X (void) strcpy(file, tmp);
- X else {
- X char *home = do_set(set_options, "home");
- X if (!home || !*home)
- X home = ALTERNATE_HOME;
- X /* if .mushrc doesn't exist, check .mailrc. If neither, force .mushrc */
- X if (Access(sprintf(file, "%s/%s", home, MAILRC), F_OK) &&
- X Access(sprintf(file, "%s/%s", home, ALTERNATE_RC), F_OK))
- X (void) sprintf(file, "%s/%s", home, MAILRC);
- X }
- X
- X cnt = 1;
- X tmp = getpath(file, &cnt);
- X if (cnt) {
- X if (cnt == -1) {
- X print("%s: %s\n", file, tmp);
- X return -1;
- X } else {
- X print("%s is a directory.\n", tmp);
- X return -2;
- X }
- X }
- X /* See if the file exists and confirm overwrite */
- X if (!Access(tmp, F_OK)) {
- X int overwrite = TRUE;
- X char buf[BUFSIZ];
- X if (!istool) {
- X print("\"%s\" exists. Overwrite? ", trim_filename(tmp));
- X if (Getstr(buf, 3, 0) <= 0 || lower(*buf) != 'y')
- X overwrite = FALSE;
- X }
- #ifdef SUNTOOL
- X else {
- X sprintf(buf, "\"%s\" exists. Overwrite? ", trim_filename(tmp));
- X overwrite = ask(buf);
- X }
- #endif /* SUNTOOL */
- X if (!overwrite) {
- X print("\"%s\" unchanged.\n", tmp);
- X return -3;
- X }
- X }
- X if (!(fp = fopen(tmp, "w"))) {
- X error("Can't open %s", file);
- X return -1;
- X }
- X
- X save_list("basic variable settings", set_options, "set", '=', fp);
- X
- X save_list("mail headers for outgoing mail", own_hdrs, "my_hdr", 0, fp);
- X
- X save_list("aliases", aliases, "alias", 0, fp);
- X
- X (void) alts(0, (char **)fp);
- X
- X save_list("headers to ignore", ignore_hdr, "ignore", ' ', fp);
- X
- X save_list("command abbreviations", functions, "cmd", ' ', fp);
- X
- X save_list("command macros for function keys", fkeys, "fkey", ' ', fp);
- X
- #ifdef CURSES
- X save_cmd("curses mode key bindings", cmd_map, "bind", 1, fp);
- #endif /* CURSES */
- X
- X save_cmd("line mode mappings", line_map, "map", 0, fp);
- X
- X save_cmd("composition mode mappings", bang_map, "map!", 0, fp);
- X
- X (void) fclose(fp);
- X print("All variables and options saved in %s\n", trim_filename(tmp));
- X return 0;
- }
- X
- save_list(title, list, command, equals, fp)
- struct options *list;
- register char *command, *title, equals;
- register FILE *fp;
- {
- X register struct options *opts;
- X register char *p;
- X
- X if (!list)
- X return;
- X (void) fprintf(fp, "#\n# %s\n#\n", title);
- X for (opts = list; opts; opts = opts->next) {
- X if (list == set_options && !strcmp(opts->option, "cwd"))
- X continue; /* don't print $cwd */
- X (void) fprintf(fp, "%s %s", command, opts->option);
- X if (opts->value && *opts->value) {
- X register char *quote;
- X if (!equals)
- X quote = NO_STRING;
- X else if (p = any(opts->value, "\"'"))
- X if (*p == '\'')
- X quote = "\"";
- X else
- X quote = "'";
- X else
- X if (!any(opts->value, " \t;|"))
- X quote = NO_STRING;
- X else
- X quote = "'";
- X (void) fputc(equals? equals: ' ', fp);
- X (void) fprintf(fp, "%s%s%s", quote, opts->value, quote);
- X }
- X (void) fputc('\n', fp);
- X }
- }
- X
- extern struct cmd_map map_func_names[];
- X
- save_cmd(title, list, command, equals, fp)
- struct cmd_map *list;
- register char *command, *title;
- register int equals;
- register FILE *fp;
- {
- X register struct cmd_map *opts;
- X register char *p;
- X char buf[MAX_MACRO_LEN * 2];
- X
- X if (!list)
- X return;
- X (void) fprintf(fp, "#\n# %s\n#\n", title);
- X for (opts = list; opts; opts = opts->m_next) {
- X register char *quote;
- X if ((p = any(opts->m_str, "\"'")) && *p == '\'')
- X quote = "\"";
- X else
- X quote = "'";
- X (void) fprintf(fp, "%s %s%s%s", command, quote,
- X ctrl_strcpy(buf, opts->m_str, TRUE), quote);
- X if (equals && map_func_names[opts->m_cmd].m_str)
- X (void) fprintf(fp, " %s", map_func_names[opts->m_cmd].m_str);
- X if (opts->x_str && *opts->x_str) {
- X if ((p = any(opts->x_str, "\"'")) && *p == '\'')
- X quote = "\"";
- X else
- X quote = "'";
- X (void) fprintf(fp, " %s%s%s", quote,
- X ctrl_strcpy(buf, opts->x_str, TRUE), quote);
- X }
- X (void) fputc('\n', fp);
- X }
- }
- X
- /*
- X * do_alias handles aliases, header settings, functions, and fkeys.
- X * since they're all handled in the same manner, the same routine is
- X * used. argv[0] determines which to use.
- X * alias is given here as an example
- X *
- X * alias identify all aliases
- X * alias name identify alias
- X * alias name arg1 arg2 arg3... -> name="arg1 arg2 arg3"; call add_option
- X * unalias arg1 [arg2 arg3 ... ] unalias args
- X *
- X * same is true for dealing with your own headers.
- X * (also the expand command)
- X */
- do_alias(argc, argv)
- register char **argv;
- {
- X register char *cmd = *argv, *p;
- X struct options **list;
- X char firstchar = *cmd, buf[BUFSIZ];
- X
- X if (argc == 0)
- X return 0 - in_pipe();
- X if (firstchar == 'u')
- X firstchar = cmd[2];
- X if (*++argv && !strcmp(*argv, "-?")) { /* doesn't apply for fkeys */
- X register char *help_str;
- X if (firstchar == 'a' || firstchar == 'e')
- X help_str = "alias";
- X else if (firstchar == 'c')
- X help_str = "cmd";
- X else if (firstchar == 'f')
- X help_str = "fkey";
- X else
- X help_str = "my_hdr";
- X return help(0, help_str, cmd_help);
- X }
- X
- X if (firstchar == 'a')
- X list = &aliases;
- X else if (firstchar == 'c')
- X list = &functions;
- X else if (firstchar == 'f')
- X list = &fkeys;
- X else
- X list = &own_hdrs;
- X
- X if (*cmd == 'u') {
- X if (!*argv) {
- X print("%s what?\n", cmd);
- X return -1;
- X /* unset a list separated by spaces or ',' */
- X } else while (*argv) {
- X if (!strcmp(*argv, "*")) /* unset everything */
- X while (*list)
- X (void) un_set(list, (*list)->option);
- X else if (!un_set(list, *argv))
- X print("\"%s\" isn't set\n", *argv);
- X argv++;
- X }
- #ifdef SUNTOOL
- X if (istool > 1)
- X update_list_textsw(list);
- #endif /* SUNTOOL */
- X return 0;
- X }
- X
- X if (!*argv && *cmd != 'e') {
- X /* just type out all the aliases or own_hdrs */
- X (void) do_set(*list, NULL);
- X return 0;
- X }
- X
- X if (*cmd == 'e') { /* command was "expand" (aliases only) */
- X if (!*argv) {
- X print("expand which alias?\n");
- X return -1;
- X } else
- X do {
- X print("%s: ", *argv);
- X if (p = alias_to_address(*argv))
- X print("%s\n", p);
- X } while (*++argv);
- X return 0;
- X }
- X
- X /* at this point, *argv now points to a variable name ...
- X * check for hdr -- if so, *argv better end with a ':' (check *p)
- X */
- X if (list == &own_hdrs && !(p = index(*argv, ':'))) {
- X print("header labels must end with a ':' (%s)\n", *argv);
- X return -1;
- X }
- X if (!argv[1] && !index(*argv, '='))
- X if (p = do_set(*list, *argv))
- X print("%s\n", p);
- X else
- X print("%s is not set\n", *argv);
- X else {
- X char *tmpargv[2];
- X (void) argv_to_string(buf, argv);
- X if ((p = any(buf, " \t=")) && *p != '=')
- X *p = '=';
- X /* if we're setting an alias, enforce the insertion of commas
- X * between each well-formed address.
- X */
- X if (list == &aliases)
- X fix_up_addr(p+1);
- X tmpargv[0] = buf;
- X tmpargv[1] = NULL;
- X (void) add_option(list, tmpargv);
- #ifdef SUNTOOL
- X if (istool > 1)
- X update_list_textsw(list);
- #endif /* SUNTOOL */
- X }
- X return 0;
- }
- SHAR_EOF
- chmod 0644 setopts.c ||
- echo 'restore of setopts.c failed'
- Wc_c="`wc -c < 'setopts.c'`"
- test 21221 -eq "$Wc_c" ||
- echo 'setopts.c: original size 21221, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= signals.c ==============
- if test -f 'signals.c' -a X"$1" != X"-c"; then
- echo 'x - skipping signals.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting signals.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'signals.c' &&
- /* @(#)signals.c (c) copyright 10/18/86 (Dan Heller) */
- X
- #include "mush.h"
- X
- #ifdef SUNTOOL
- extern int compose_destroy;
- #endif
- X
- static int was_stopped;
- X
- #ifndef SYSV
- extern char *sys_siglist[];
- #else
- /* sys-v doesn't have normal sys_siglist */
- static char *sys_siglist[] = {
- /* no error */ "no error",
- /* SIGHUP */ "hangup",
- /* SIGINT */ "interrupt (rubout)",
- /* SIGQUIT */ "quit (ASCII FS)",
- /* SIGILL */ "illegal instruction (not reset when caught)",
- /* SIGTRAP */ "trace trap (not reset when caught)",
- /* SIGIOT */ "IOT instruction",
- /* SIGEMT */ "EMT instruction",
- /* SIGFPE */ "floating point exception",
- /* SIGKILL */ "kill (cannot be caught or ignored)",
- /* SIGBUS */ "bus error",
- /* SIGSEGV */ "segmentation violation",
- /* SIGSYS */ "bad argument to system call",
- /* SIGPIPE */ "write on a pipe with no one to read it",
- /* SIGALRM */ "alarm clock",
- /* SIGTERM */ "software termination signal from kill",
- /* SIGUSR1 */ "user defined signal 1",
- /* SIGUSR2 */ "user defined signal 2",
- /* SIGCLD */ "death of a child",
- /* SIGPWR */ "power-fail restart"
- };
- #endif /* SYSV */
- X
- SIGRET
- intrpt(sig)
- {
- X if (!was_stopped)
- X Debug("interrupt() caught: %d\n", sig);
- X mac_flush();
- X turnon(glob_flags, WAS_INTR);
- }
- X
- /*
- X * catch signals to reset state of the machine. Always print signal caught.
- X * If signals are ignored, return. If we're running the shell, longjmp back.
- X */
- /*ARGSUSED*/
- SIGRET
- catch(sig)
- {
- X if (!was_stopped)
- X Debug("Caught signal: %d\n", sig);
- X (void) signal(sig, catch);
- X if (ison(glob_flags, IGN_SIGS) && sig != SIGTERM && sig != SIGHUP)
- X return;
- X mac_flush();
- X turnoff(glob_flags, IS_PIPE);
- X if (istool || sig == SIGTERM || sig == SIGHUP) {
- #ifdef SUNTOOL
- X if (istool > 1) { /* istool is 2 if tool is complete */
- X if (compose_destroy) {
- X if (sig == SIGTERM) /* tty_sw is dying */
- X return;
- X if (sig == SIGHUP) { /* compose frame went away */
- X compose_destroy = 0;
- X compose_frame = 0;
- X return;
- X }
- X }
- #ifndef SUN_4_0
- X /* spurious SIGHUPs in 3.5 */
- X if (sig == SIGHUP && window_get(tool, WIN_SHOW))
- X return;
- #endif /* SUN_4_0 */
- X istool = 1;
- X }
- #endif /* SUNTOOL */
- X if (!was_stopped)
- X print("%s: %s\n", prog_name, sys_siglist[sig]);
- X (void) setjmp(jmpbuf);
- X if (ison(glob_flags, IS_GETTING))
- X rm_edfile(-1);
- X cleanup(sig);
- X }
- X if (!was_stopped)
- X print("%s: %s\n", prog_name, sys_siglist[sig]);
- X if (ison(glob_flags, DO_SHELL)) {
- X /* wrapcolumn may have been trashed -- restore it */
- X if (ison(glob_flags, IS_GETTING)) {
- X char *fix = do_set(set_options, "wrapcolumn");
- X if (fix && *fix)
- X wrapcolumn = atoi(fix);
- X }
- X turnoff(glob_flags, IS_GETTING);
- #ifdef SYSV
- X /* Interrupting "await" leaves an alarm timer running, which
- X * some SysV systems mishandle. Clean up.
- X */
- X if (!istool)
- X (void) signal(SIGALRM, SIG_IGN);
- #endif /* SYSV */
- X longjmp(jmpbuf, 1);
- X } else {
- X if (!was_stopped)
- X puts("exiting");
- X cleanup(sig);
- X }
- }
- X
- #ifdef SIGCONT
- #ifdef SIGTTOU
- jmp_buf ttoubuf;
- X
- SIGRET
- tostop(sig)
- {
- X (void) signal(SIGTTOU, SIG_DFL);
- X if (was_stopped)
- X longjmp(ttoubuf, 1);
- }
- #endif /* SIGTTOU */
- X
- SIGRET
- stop_start(sig)
- {
- X extern FILE *ed_fp;
- X
- X Debug("Caught signal: %d", sig);
- X if (sig == SIGCONT) {
- X (void) signal(SIGTSTP, stop_start);
- X (void) signal(SIGCONT, stop_start);
- #ifdef SIGTTOU
- X /* Restoring echo mode may cause a SIGTTOU if mush was killed
- X * while in the background. Jump around the echo_off() call if
- X * we get a TTOU when attempting it. Leave was_stopped on in
- X * this case, and don't do all the associated prompting.
- X */
- X (void) signal(SIGTTOU, tostop);
- X if (setjmp(ttoubuf) == 0) {
- X echo_off();
- X was_stopped = 0;
- X }
- #ifdef CURSES
- X else
- X iscurses = 0;
- #endif /* CURSES */
- #endif /* SIGTTOU */
- X if (istool || was_stopped || ison(glob_flags, IGN_SIGS) && !iscurses)
- X return;
- X /* we're not in an editor but we're editing a letter */
- X if (ison(glob_flags, IS_GETTING)) {
- X if (ed_fp)
- X print("(Continue editing letter)\n");
- X }
- #ifdef CURSES
- X else if (iscurses)
- X if (ison(glob_flags, IGN_SIGS)) {
- X clr_bot_line();
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X mail_status(1), addstr("...continue... ");
- X refresh();
- X } else {
- X int curlin = max(1, current_msg - n_array[0] + 1);
- X redraw();
- X print("Continue");
- X move(curlin, 0);
- X refresh();
- X /* make sure we lose reverse video on continuation */
- X if (ison(glob_flags, REV_VIDEO) && msg_cnt) {
- X char buf[256];
- X (void) strncpy(buf, compose_hdr(current_msg), COLS-1);
- X buf[COLS-1] = 0; /* strncpy does not null terminate */
- X mvaddstr(curlin, 0, buf);
- X }
- X }
- #endif /* CURSES */
- X else
- X mail_status(1), (void) fflush(stdout);
- X } else {
- #ifdef CURSES
- X if (iscurses) {
- X /* when user stops mush, the current header is not in reverse
- X * video -- note that a refresh() has not been called in curses.c!
- X * so, make sure that when a continue is called, the reverse video
- X * for the current message returns.
- X */
- X turnon(glob_flags, WAS_INTR);
- X if (isoff(glob_flags, IGN_SIGS) && ison(glob_flags, REV_VIDEO) &&
- X msg_cnt) {
- X int curlin = max(1, current_msg - n_array[0] + 1);
- X char buf[256];
- X scrn_line(curlin, buf);
- X STANDOUT(curlin, 0, buf);
- X }
- X print("Stopping...");
- X }
- #endif /* CURSES */
- X echo_on();
- X (void) signal(SIGTSTP, SIG_DFL);
- X (void) signal(SIGCONT, stop_start);
- X was_stopped = 1;
- X (void) kill(getpid(), sig);
- X }
- }
- #endif /* SIGCONT */
- X
- /*ARGSUSED*/
- void
- cleanup(sig)
- {
- X char buf[128], c;
- X
- X if (sig != SIGTERM && sig != SIGHUP && ison(glob_flags, IGN_SIGS))
- X c = 'n';
- X else
- X c = 'y';
- X
- #ifdef CURSES
- X if (iscurses && sig != SIGHUP)
- X iscurses = FALSE, endwin();
- #endif /* CURSES */
- X
- X if (!was_stopped)
- X echo_on();
- X
- X if (ison(glob_flags, IS_GETTING))
- X turnoff(glob_flags, IS_GETTING), dead_letter(sig);
- X if ((sig == SIGSEGV || sig == SIGBUS) && isoff(glob_flags, IGN_SIGS)
- X && *tempfile && !istool) {
- X (void) fprintf(stderr, "remove %s [y]? ", tempfile), (void) fflush(stderr);
- X if (fgets(buf, sizeof(buf), stdin))
- X c = lower(*buf);
- X }
- X if (c != 'n' && *tempfile) {
- X if (sig == SIGHUP && do_set(set_options, "hangup") &&
- X copyback(NULL, TRUE) && isoff(glob_flags, CORRUPTED))
- X (void) unlink(tempfile);
- X else if (unlink(tempfile) && !sig && errno != ENOENT)
- X error(tempfile);
- X }
- X if (sig == SIGSEGV || sig == SIGBUS) {
- X if (isoff(glob_flags, IGN_SIGS) && !istool) {
- X (void) fprintf(stderr, "coredump [n]? "), (void) fflush(stderr);
- X if (fgets(buf, sizeof(buf), stdin))
- X c = lower(*buf);
- X }
- X if (c == 'y') {
- X if (!istool)
- X puts("dumping core for debugging");
- X abort();
- X }
- X }
- X exit(sig);
- }
- X
- long last_spool_size = -1; /* declared here cuz it's initialized here */
- X
- #ifdef SUNTOOL
- Notify_value
- do_check()
- {
- X if (isoff(glob_flags, IGN_SIGS))
- X (void) check_new_mail();
- X return (NOTIFY_DONE) ;
- }
- #endif /* SUNTOOL */
- X
- /*
- X * Get any new mail that has arrived. This function assumes that a
- X * call to mail_size() has already been done, so that last_spool_size
- X * can be compared to spool_size to decide what should be done.
- X *
- X * The value for last_spool_size is updated to the new spool_size only
- X * if update_size is TRUE. check_new_mail() depends on the -1 initial
- X * value of last_spool_size for correct "New mail" messages, so it
- X * uses FALSE and updates last_spool_size itself.
- X */
- get_new_mail(update_size)
- int update_size;
- {
- X if (last_spool_size > spool_size && !strcmp(mailfile, spoolfile)) {
- X print("Someone changed \"%s\"! ", mailfile);
- X if (update_size)
- X return 1; /* Don't reinit if called from copyback() */
- X print_more("Reinitializing...\n");
- X if (isoff(glob_flags, READ_ONLY))
- X (void) emptyfile(&tmpf, tempfile);
- X current_msg = msg_cnt = 0;
- X turnoff(glob_flags, CORRUPTED);
- X }
- X if (ison(glob_flags, CORRUPTED))
- X return 0;
- X if (load_folder(mailfile, 1, NULL) < 1) {
- X print("Can't load new mail: \"%s\" may be corrupted!\n", mailfile);
- X turnon(glob_flags, CORRUPTED);
- X return update_size;
- X /* NOTE: The above is used to stop check_new_mail() from calling
- X * show_new_mail(), while still allowing copyback() to detect the
- X * possible error and to query about updating the folder. There
- X * should be a better-defined way to handle this.
- X */
- X }
- X /* Prevent both bogus "new mail" messages and missed new mail */
- X last_size = msg[msg_cnt].m_offset;
- X if (!strcmp(mailfile, spoolfile)) {
- X spool_size = last_size;
- X if (last_spool_size != spool_size)
- X turnon(glob_flags, NEW_MAIL);
- X } else if (last_spool_size < spool_size)
- X turnon(glob_flags, NEW_MAIL);
- X if (msg_cnt && current_msg < 0)
- X current_msg = 0;
- X if (last_spool_size != spool_size) {
- X if (update_size)
- X last_spool_size = spool_size;
- X return 1;
- X }
- X return 0;
- }
- X
- #ifdef SUNTOOL
- int is_iconic, was_iconic;
- #endif /* SUNTOOL */
- X
- /*
- X * Display a summary when new mail has come in. sprintf it all into one
- X * buffer and print that instead of separate print statements to allow
- X * the tool mode to make one print statement. The reason for this is that
- X * when the tool is refreshed (caused by a resize, reopen, move, top, etc)
- X * the last thing printed is displayed -- display the entire line.
- X */
- show_new_mail()
- {
- X char buf[BUFSIZ];
- X register char *p = buf;
- X int noisy = !chk_option("quiet", "newmail");
- #ifdef CURSES
- X int new_hdrs = last_msg_cnt;
- #endif /* CURSES */
- X
- X if (msg_cnt == last_msg_cnt)
- X return 1; /* Nothing to print */
- #ifdef SUNTOOL
- X if (istool) {
- X mail_status(0);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X if (noisy && !chk_option("quiet", "tool"))
- X bell();
- X }
- #endif /* SUNTOOL */
- X if (msg_cnt < last_msg_cnt) {
- X last_msg_cnt = msg_cnt;
- X if (!istool)
- X mail_status(0);
- X if (iscurses && isoff(glob_flags, CNTD_CMD))
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X return 0;
- X }
- X if (noisy) {
- X p += Strcpy(p, "New mail ");
- X if (msg_cnt - last_msg_cnt <= 1)
- X p += strlen(sprintf(p, "(#%d) ", msg_cnt));
- X else
- X p += strlen(sprintf(p, "(#%d thru #%d)\n", last_msg_cnt+1,msg_cnt));
- X }
- #ifdef SUNTOOL
- X /*
- X * If mush is in tool mode and in icon form, don't update
- X * last_msg_cnt so that when the tool is opened, print() will
- X * print the correct number of "new" messages.
- X */
- X if (istool && (was_iconic = (int) window_get(tool, FRAME_CLOSED)))
- X (void) strcpy(p, "\n");
- X else
- #endif /* SUNTOOL */
- X {
- X if (!noisy || iscurses && isoff(glob_flags, CNTD_CMD))
- X last_msg_cnt = msg_cnt;
- X else while (last_msg_cnt < msg_cnt) {
- X char *p2 = compose_hdr(last_msg_cnt++) + 9;
- X if (strlen(p2) + (p - buf) >= BUFSIZ-5) {
- X (void) strcpy(p, "...\n");
- X /* force a break by setting last_msg_cnt correctly */
- X last_msg_cnt = msg_cnt;
- X } else
- X p += strlen(sprintf(p, " %s\n", p2));
- X }
- X }
- #ifdef CURSES
- X if (iscurses && isoff(glob_flags, CNTD_CMD)) {
- X if (new_hdrs - n_array[screen-1] < screen)
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X print("%s ...", buf);
- X } else
- #endif /* CURSES */
- X if (noisy)
- X print("%s", buf); /* buf might have %'s in them!!! */
- X return 1;
- }
- X
- /*
- X * Look for new mail and read it in if any has arrived.
- X * return 0 if no new mail, 1 if new mail and -1 if new mail is in system
- X * folder, but current mbox is not system mbox.
- X */
- check_new_mail()
- {
- X int ret_value;
- X
- X if (ret_value = mail_size()) {
- #ifdef SUNTOOL
- X /* if our status has changed from icon to open window, then
- X * there will already be a message stating number of new
- X * messages. reset `n' to msg_cnt so we don't restate
- X * the same # of new messages upon receipt of yet another new message.
- X */
- X if (istool && !(is_iconic = ((int) window_get(tool, FRAME_CLOSED))) &&
- X was_iconic)
- X last_msg_cnt = msg_cnt;
- #endif /* SUNTOOL */
- X if (get_new_mail(0) && !show_new_mail())
- X return 0;
- X } else
- #ifdef SUNTOOL
- X if (!istool || !is_iconic)
- #endif /* SUNTOOL */
- X turnoff(glob_flags, NEW_MAIL);
- X if (last_spool_size > -1 && /* handle first case */
- X strcmp(mailfile, spoolfile) && last_spool_size < spool_size)
- X print("You have new mail in your system mailbox.\n"), ret_value = -1;
- X last_spool_size = spool_size;
- X return ret_value;
- }
- X
- /*ARGSUSED*/ /* we ignore the sigstack, cpu-usage, etc... */
- SIGRET
- bus_n_seg(sig)
- {
- X (void) signal(sig, SIG_DFL);
- SHAR_EOF
- true || echo 'restore of signals.c failed'
- fi
- echo 'End of part 20'
- echo 'File signals.c is continued in part 21'
- echo 21 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-